package org.softmed.rest.editor.comps;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;

import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import net.miginfocom.swing.MigLayout;

import org.restlet.Client;
import org.restlet.data.MediaType;
import org.restlet.data.Protocol;
import org.restlet.data.Response;
import org.restlet.resource.StringRepresentation;
import org.softmed.rest.editor.EditorUtil;
import org.softmed.rest.editor.commons.SwingUtil;
import org.softmed.rest.editor.commons.URIProvider;
import org.softmed.rest.editor.config.Application;
import org.softmed.rest.editor.xml.XStreamConfigurator;

import com.thoughtworks.xstream.XStream;

public abstract class ApplicationEditor extends SimpleEditor implements
		ActionListener {
	protected Application application;

	protected CustomTextField name = new CustomTextField();
	protected CustomTextField relativeURI = new CustomTextField();
	protected JCheckBox active = new JCheckBox();
	protected JLabel id = new JLabel("id");

	public ApplicationEditor(URIProvider uriProvider) {
		super(uriProvider);
		uri = "applications";

		XStreamConfigurator.configureStreamerApplication(streamer);

		active.addActionListener(this);
		name.addActionListener(this);
		relativeURI.addActionListener(this);
		// setup();
	}

	public void createNew() throws Throwable {

		String xml = streamer.toXML(new Application());
		Response response = client.post(getClassURI(),
				new StringRepresentation(xml, MediaType.APPLICATION_XML));
		if (response.getStatus().getCode() != 201)
			throw new RuntimeException("Error creating application with xml;"
					+ xml);
		xml = response.getEntity().getText();
		application = (Application) streamer.fromXML(xml);
		setEntity(application);

	}

	public void setEntity(Object app) throws Throwable {
		application = (Application) app;
		active.setSelected(application.isActive());
		name.setText(application.getName());
		relativeURI.setText(application.getRelativeUri());
		id.setText(application.getId().toString());
		repaint();
	}

	public void loadEntity(String uri) throws Throwable {
		Response response = client.get(uri);
		if (response.getStatus().getCode() != 200)
			throw new RuntimeException("Error fetching entity " + uri);
		String xml = response.getEntity().getText();
		application = (Application) streamer.fromXML(xml);
		setEntity(application);
	}

	public void refresh() throws Throwable {
		loadEntity(application.getUri());
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		super.actionPerformed(e);

		if (!editable)
			return;

		try {
			Object source = e.getSource();
			if (source == active) {
				active.setForeground(Color.RED);
				showUpdatePanel();
				Response response = client.put(getInstanceURI() + "/"
						+ "active", new StringRepresentation(active
						.isSelected()
						+ ""));
				hideUpdatePanel();
				if (response.getStatus().getCode() != 200)
					throw new RuntimeException(
							"Error changing app active state to "
									+ active.isSelected());
				active.setForeground(Color.BLACK);
			} else if (source == name) {
				EditorUtil
						.saveTextField(client, getInstanceURI(), name, "name");
			} else if (source == relativeURI) {
				EditorUtil.saveTextField(client, getInstanceURI(), relativeURI,
						"relative-uri");
			}
		} catch (Throwable t) {
			t.printStackTrace();
			JOptionPane.showMessageDialog(this, t.getMessage(), "Error",
					JOptionPane.ERROR_MESSAGE);
		}
	}

	private String getInstanceURI() {
		return getClassURI() + "/" + application.getId();
	}

	public void addMouseListener(MouseListener list) {
		super.addMouseListener(list);
		active.addMouseListener(list);
		name.addMouseListener(list);
		relativeURI.addMouseListener(list);
	}

	public void removeMouseListener(MouseListener list) {
		super.removeMouseListener(list);
		active.removeMouseListener(list);
		name.removeMouseListener(list);
		relativeURI.removeMouseListener(list);
	}

	public void setEditable(boolean editable) {
		this.editable = editable;
		active.setEnabled(editable);
		name.setEditable(editable);
		relativeURI.setEditable(editable);

		name.setDetectChanges(editable);
		relativeURI.setDetectChanges(editable);
	}

	@Override
	public Object getEntity() {
		return application;
	}

	// @Override
	// public void setup() throws Throwable {
	// // TODO Auto-generated method stub
	//
	// }

}
